
package com.oswego.dawcs;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.StrictMode;
import android.app.Activity;
import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.InputType;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class DAWCS extends Activity {
    private final static ArrayList<ChannelController> channelList = new ArrayList<ChannelController>();
    private static final int MAX_NUM_CHANNELS = 16;

    public static final int NUM_STREAMS = 1;

    public static final Channels chans = new Channels();

    public static ArrayList<Channel> availableChans = new ArrayList<Channel>();
    public static HashMap<Integer, Group> groupsMap = new HashMap<Integer, Group>();

    private static Theme currentTheme = Theme.ORIGINAL;

    public static AvailableChannelTracker act;
    
    private int numChans;
    public static int defaultNumChannels = 8;

    private boolean click = true;
    public static boolean reset = false;

    HashMap<ChannelController, View> bufferMap = new HashMap<ChannelController, View>();

    // Database Stuff
    // I'm coming back to this... I need to get lunch - Marcus
//    DatabaseHandler db = new DatabaseHandler(this);
//    Layout template = new Layout(1, "Template 1", 1);
//    ChannelData chanData = new ChannelData(0, 0, 0, 0, 0, 0, 0);
    //-------------------------------------------------------------
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        act = new AvailableChannelTracker(MAX_NUM_CHANNELS);

        setContentView(R.layout.activity_dawcs);

        NonFocusingHorizontalScrollView hsv = (NonFocusingHorizontalScrollView) findViewById(R.id.scroll1);
        
        for (int i = 0; i < 4; i++) {
        	Group group = new Group();
        	group.setGroupID(i + 1);
        	groupsMap.put(i + 1, group);

        }

        for(int i=1;i<=MAX_NUM_CHANNELS;i++){
            Channel c = new Channel(i, false);
            availableChans.add(c);
            chans.add(c);
        }

        //load the default number channels on load
        for (int i = 1; i <= defaultNumChannels; i++) {
			addChannel((LinearLayout)findViewById(R.id.chanHolder), chans.getChan(i));
		}

        NetHandler.getInstance().setWifiManager(((WifiManager) this.getSystemService(DAWCS.WIFI_SERVICE)));
       
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        NetHandler.getInstance().invokeListenerThread();

    }

    @Override public void onResume(){
        super.onResume();
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
        int themeId = sp.getInt("theme", -1);
        Theme t = Theme.getThemeFromId(themeId);
        setTheme(t);

        boolean newClick = sp.getBoolean("click", true);
        if(newClick != click){
            click = newClick;
            setClickForChannels();
        }

        defaultNumChannels = sp.getInt("default", 8);

        if(reset){
            resetChannelList();
            reset = false;
        }
    }

    //USE WITH CAUTION!!:
    //this method removes ALL channels from the gui and reloads the list with the default
    //number of channels
    private void resetChannelList(){
        LinearLayout ll = (LinearLayout)findViewById(R.id.chanHolder);
        for(ChannelController cc : channelList){
            removeChannel(cc, ll);
        }
        channelList.clear();
        for(int i=1;i<=defaultNumChannels;i++){
            addChannel(ll, chans.getChan(i));
        }
    }

    private void setClickForChannels(){
        for(ChannelController cc : channelList){
            cc.setClick(click);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.dawc, menu);
        
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.add_button:
                if (!act.maxChannelsAdded()) {
                    Channel newChan = chans.getChan(act.getNextChanNum());
                    addChannel((LinearLayout)findViewById(R.id.chanHolder), newChan);
                } else{

                    AlertDialog chansFullAlert = new AlertDialog.Builder(this)
                            .setTitle("I'm sorry Dave, I'm afraid I can't do that")
                            .setMessage("There are already " + MAX_NUM_CHANNELS + " channels loaded." +
                                    "No more can fit!!")
                            .create();
                    chansFullAlert.show();

//                    Toast.makeText(this, "Maximum number of channels already added.", Toast.LENGTH_LONG);
//                    return false;
                }
                return true;
            case R.id.action_settings:
                Intent i = new Intent(this, Settings.class);
                startActivity(i);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    
    public boolean addChannel(final LinearLayout ll, Channel chan){


        if (!act.maxChannelsAdded()) {
            act.addChannel(chan.getChanID());
//            chans.add(chan);
            availableChans.remove(chan);


            final ChannelController newChannel = new ChannelController(this, true, true, true, chan, click);
            newChannel.addCloseListener(new OnClickListener() {
                @Override
                public void onClick(View arg0) {
                    removeChannel(newChannel, ll);
                }
            });
            setTheme(currentTheme, newChannel);

            ll.addView(newChannel);
            genBufferView(newChannel);
            ll.addView(bufferMap.get(newChannel));

            numChans++;

            channelList.add(newChannel);

            updateAvailableChannels();
            return true;

        } else{
            Toast.makeText(this, "Maximum number of channels already added.", Toast.LENGTH_LONG);
            return false;
        }

    }
    public void removeChannel(ChannelController cc, LinearLayout ll){
    	chans.getChan(cc.getChannelNum()).setExists(false);
    	if (availableChans.isEmpty()) {
    		availableChans.add(chans.getChan(cc.getChannelNum()));
    	} else {
    		availableChans.add(chans.getChan(cc.getChannelNum()));
    		sortAvailableChans();
    	}
        ll.removeView(cc);
        ll.removeView(bufferMap.get(cc));
        bufferMap.remove(cc);
        numChans--;

        act.removeChannel(cc.getChannelNum());

        updateAvailableChannels();
    }
    
    private void sortAvailableChans() {
    	for (int i = 0; i < availableChans.size(); i ++) {
    		for (int j = availableChans.size() - 1; j >= (i + 1); j--) {
    			if (availableChans.get(j).getChanID() < availableChans.get(j - 1).getChanID()) {
    				Channel tmp = availableChans.get(j);
    				availableChans.set(j, availableChans.get(j - 1));
    				availableChans.set(j - 1, tmp);
    			}
    		}
    	}
    }
    
    private Channel makeNewChan() {
//    	if (chans.isEmpty()) {
//    		chan = new Channel(1, false);
//    	} else {
//    		chan = new Channel(chans.size() + 1, false);
//    	}
    	return new Channel(act.getNextChanNum(), false);
    }
    
    private void genBufferView(ChannelController cc){
    	TextView t = new TextView(getBaseContext());
    	t.setText("  ");
    	
    	bufferMap.put(cc, t);
    }
    
    private void setTheme(Theme t){
        currentTheme = t;
    	for(ChannelController cc : channelList){
    		cc.setPanImgById(t.getKnobID());
    		cc.setSliderImgsByIds(t.getThumbID(), t.getSeekbarBackgroundID());
    		cc.setEQImgsById(t.getKnobID());
            cc.setCloseButtonById(t.getCloseButtonID());
    	}
    }

    private void setTheme(Theme t, ChannelController cc){
        cc.setPanImgById(t.getKnobID());
        cc.setSliderImgsByIds(t.getThumbID(), t.getSeekbarBackgroundID());
        cc.setEQImgsById(t.getKnobID());
        cc.setCloseButtonById(t.getCloseButtonID());
    }
    
    public static void updateAvailableChannels(){
        for(ChannelController cc : channelList){
            cc.updateAvailableChannels(act.getAvailableChannelList());
        }
    }

    public static List<Integer> getAvailableChannelNumbers(){
        return act.getAvailableChannelList();
    }

    public static void removeAvailableChan(int chan){
        act.addChannel(chan);
        updateAvailableChannels();
    }

    public static void addAvailableChan(int chan){
        act.removeChannel(chan);
        updateAvailableChannels();
    }

    /*
    * The following private class is used for tracking the list
    * of available channels, up to the max
    */
    private class AvailableChannelTracker{
        private int maxChannels;

        private int currentNumChannels = 0;
        private boolean isFull = false;

        private ArrayList<Integer> availChans;

        public AvailableChannelTracker(int max){
            this.maxChannels = max;
            availChans = new ArrayList<Integer>();
            for(int i=1;i< maxChannels +1;i++){
                availChans.add(i);
            }
        }

        //this method should be called whenever a new channel is added to the gui.
        //any channels added here will be REMOVED from the list of available channels.
        public int addChannel(int chan){
                currentNumChannels = currentNumChannels +1;
                for(int i=0;i<availChans.size();i++){
                    if(availChans.get(i) == chan){
                        availChans.remove(i);
                    }
                }

            Collections.sort(availChans);

            System.out.println("Available channels size: " + availChans.size());
            System.out.println("Number of channels in gui: " + currentNumChannels);
            System.out.println("Max number of channels: " + maxChannels);
            System.out.println("Max channels added yet?: " + maxChannelsAdded());

            if(currentNumChannels == maxChannels){
                isFull = true;
            }

            return currentNumChannels;
        }

        //this method should be called whenever a channel is removed from the gui.
        //upon removal, the channel number will be ADDED to the list of available channels.
        public int removeChannel(Integer chan){
            if(!availChans.contains(chan)){
                currentNumChannels = currentNumChannels -1;
                availChans.add(chan);
            }

            if(currentNumChannels == maxChannels){
                isFull = true;
            } else{
                isFull = false;
            }

            Collections.sort(availChans);

            System.out.println("Available channels size: " + availChans.size());
            System.out.println("Number of channels in gui: " + currentNumChannels);
            System.out.println("Max number of channels: " + maxChannels);
            System.out.println("Max channels added yet?: " + maxChannelsAdded());
//            System.out.println("Next avail chan num: " + getNextChanNum());

            return currentNumChannels;
        }

        //this method simply returns true or false depending on whether
        //the max # of channels has been added
        public boolean maxChannelsAdded(){
            return isFull;
        }

        //method to return proper int value of next channel #
        public int getNextChanNum(){
            return availChans.get(0);
        }

        public List<Integer> getAvailableChannelList(){
            return availChans;
        }
    }
}
    
